<?php

namespace App\Http\Controllers\API;

use App\Services\AliService;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class AliAPIController extends Controller
{
    public $server;

    public function __construct()
    {
        $this->server = new AliService();
    }

    /**
     * @api {post} api/ali/product/create   创建产品
     * @apiVersion 1.0.0
     * @apiName createProduct
     * @apiGroup ALi
     *
     * @apiParam   {long} CatId 产品类型id
     * @apiParam   {string} ProductName 名称
     * @apiParam   {string} ProductDesc 描述
     * * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *  {
     * RequestId:8AE93DAB-958F-49BD-BE45-41353C6DEBCE,
     * Success:true,
     * ProductInfo:{
     * ProductKey:...,
     * CatId:56000,
     * ProductName:工业产品
     * }
     * }
     */
    public function createProduct(Request $request)
    {
        dump(urlencode('广州市'));
        dd(urldecode('%E5%B9%BF%E5%B7%9E%E5%B8%82'));
        $input = $request->all();
        //校验
        $rules = array("CatId" => "required",
            "ProductName" => "required",
            "ProductDesc" => "required"
        );
        $messages = array("CatId.required" => "catId为空",
            "ProductName.required" => "产品名称",
            "ProductDesc.required" => "描述");
        $result = $this->validate($input, $rules, $messages);
        if ($result["code"] != 0) {
            return $this->fail(self::VALIDATE_ERROR, $result["errors"]);
        }

        $res = $this->server->createProduct($input['CatId'], $input['ProductName'], $input['ProductDesc']);
        return $this->success($res);
    }

    /**
     * @api {post} api/ali/product/update  修改产品
     * @apiVersion 1.0.0
     * @apiName updateProduct
     * @apiGroup ALi
     *
     * @apiParam   {string} ProductKey 产品id
     * @apiParam   {long} [CatId] 产品类型id
     * @apiParam   {string} [ProductName] 名称
     * @apiParam   {string} [ProductDesc] 描述
     */
    public function updateProduct(Request $request)
    {
        $input = $request->all();
        //校验
        $rules = array("ProductKey" => "required",
        );
        $messages = array("ProductKey.required" => "产品key为空",);
        $result = $this->validate($input, $rules, $messages);
        if ($result["code"] != 0) {
            return $this->fail(self::VALIDATE_ERROR, $result["errors"]);
        }

        $res = $this->server->updateProduct($input);
        return $this->success($res);
    }

    /**
     * @api {post} api/ali/device/list  获取设备列表
     * @apiVersion 1.0.0
     * @apiName getDeviceList
     * @apiGroup ALi
     *
     * @apiParam   {string} ProductKey 产品id
     * @apiParam   {int} PageSize 页面大小
     * @apiParam   {int} CurrentPage 当前页
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     * {
     * PageCount:1,
     * Data:{
     * DeviceInfo:[
     * {DeviceId:..., DeviceName:..., ProductKey:..., DeviceSecret:..., GmtCreate:Thu, 17-Nov-2016 02:08:12 GMT, GmtModified:Thu, 17-Nov-2016 02:08:12 GMT}
     * ]
     * },
     * PageSize:10,
     * Page:1,
     * Total:9
     * RequestId:06DC77A0-4622-42DB-9EE0-26A6E1FA08D3,
     * Success:true,
     * }
     */
    public function getDeviceList(Request $request)
    {
        $input = $request->all();
        //校验
        $rules = array("ProductKey" => "required",
            "PageSize" => "required",
            "CurrentPage" => "required"
        );
        $messages = array("ProductKey.required" => "ProductKey为空",
            "PageSize.required" => "PageSize为空",
            "CurrentPage.required" => "当前页为空");
        $result = $this->validate($input, $rules, $messages);
        if ($result["code"] != 0) {
            return $this->fail(self::VALIDATE_ERROR, $result["errors"]);
        }

        $res = $this->server->getDeviceList($input['ProductKey'], $input['PageSize'], $input['CurrentPage']);
        return $this->success($res);
    }

    /**
     * @api {post} api/ali/device/register  注册设备
     * @apiVersion 1.0.0
     * @apiName deviceRegister
     * @apiGroup ALi
     *
     * @apiParam   {string} ProductKey 产品id
     * @apiParam   {string} DeviceName 设备名称
     *
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *   {
     * "RequestId":"120F5EB3-7023-4F0C-B419-9303AB336885",
     * "Success":true
     * "DeviceId":"", //阿里云颁发的设备id 全局唯一
     * "DeviceName":"",//设备名称，用户自定义或系统生成
     * "DeviceSecret":"",//设备私钥
     * "DeviceStatus":"",//预留状态字段
     * "ErrorMessage":""//错误信息
     * }
     */
    public function deviceRegister(Request $request)
    {
        $input = $request->all();
        //校验
        $rules = array("ProductKey" => "required",
            "DeviceName" => "required",
        );
        $messages = array("ProductKey.required" => "ProductKey为空",
            "DeviceName.required" => "设备名称");
        $result = $this->validate($input, $rules, $messages);
        if ($result["code"] != 0) {
            return $this->fail(self::VALIDATE_ERROR, $result["errors"]);
        }

        $res = $this->server->deviceRegister($input['ProductKey'], $input['DeviceName']);
        return $this->success($res);
    }

    /**
     * @api {post} api/ali/device/detail  根据设备名称获取设备信息
     * @apiVersion 1.0.0
     * @apiName getDeviceDetail
     * @apiGroup ALi
     *
     * @apiParam   {string} ProductKey 产品id
     * @apiParam   {string} DeviceName 设备名称,产品内唯一
     *
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *   {
     * "RequestId":"120F5EB3-7023-4F0C-B419-9303AB336885",
     * "Success":true
     * "DeviceId":"", //阿里云颁发的设备id 全局唯一
     * "DeviceName":"",//设备名称，用户自定义或系统生成
     * "DeviceSecret":"",//设备私钥
     * "DeviceStatus":"",//预留状态字段
     * "ErrorMessage":""//错误信息
     * }
     */
    public function getDeviceDetail(Request $request)
    {
        $input = $request->all();
        //校验
        $rules = array("ProductKey" => "required",
            "DeviceName" => "required",
        );
        $messages = array("ProductKey.required" => "ProductKey为空",
            "DeviceName.required" => "设备名称");
        $result = $this->validate($input, $rules, $messages);
        if ($result["code"] != 0) {
            return $this->fail(self::VALIDATE_ERROR, $result["errors"]);
        }

        $res = $this->server->getDeviceDetail($input['ProductKey'], $input['DeviceName']);
        return $this->success($res);
    }

    /**
     * @api {post} api/ali/device/status  批量获取设备状态
     * @apiVersion 1.0.0
     * @apiName getDeviceStatus
     * @apiGroup ALi
     *
     * @apiParam   {string} ProductKey 产品id
     * @apiParam   {Array} DeviceNames 设备名称列表
     *
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     * {
     * DeviceStatusList:{
     * DeviceStatus:[
     * {Status:UNACTIVE, DeviceName:...},
     * {Status:UNACTIVE, DeviceName:...}
     * ]
     * },
     * RequestId:"1A540BD7-176C-42D4-B3C0-A2C549DD00A3",
     * Success:true
     * }
     */
    public function getDeviceStatus(Request $request)
    {
        $input = $request->all();
        //校验
        $rules = array("ProductKey" => "required",
            "DeviceNames" => "required",
        );
        $messages = array("ProductKey.required" => "ProductKey为空",
            "DeviceNames.required" => "设备名称为空");
        $result = $this->validate($input, $rules, $messages);
        if ($result["code"] != 0) {
            return $this->fail(self::VALIDATE_ERROR, $result["errors"]);
        }

        $res = $this->server->getDeviceStatus($input['ProductKey'], $input['DeviceNames']);
        return $this->success($res);
    }


    /**
     * @api {post} api/ali/topic/publish  发布消息到topic
     * @apiVersion 1.0.0
     * @apiName publishToTopic
     * @apiGroup ALi
     *
     * @apiParam   {string} ProductKey 产品id
     * @apiParam   {string} TopicFullName 消息发送目的Topic名字，如/productKey/deviceName/get
     * @apiParam   {string} MessageContent 发送的消息，将消息内容二进制进行Base64编码后得到的字符串
     * @apiParam   {int} [Qos =0] 指定消息发送的方式，默认为0 0：最多发送一次，1：最少发送一次
     * 需要注意的是：消息在IoT套件中最多保存7天
     *
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     * {
     * "RequestId":"BB71E443-4447-4024-A000-EDE09922891E",
     * "Success":true,
     * "MessageId":889455942124347329
     * }
     */
    public function publishToTopic(Request $request)
    {
        $input = $request->all();
        //校验
        $rules = array("ProductKey" => "required",
            "TopicFullName" => "required",
            "MessageContent" => "required",
        );
        $messages = array("ProductKey.required" => "ProductKey为空",
            "TopicFullName.required" => "topic为空",
            "MessageContent.required" => "内容为空");
        $result = $this->validate($input, $rules, $messages);
        if ($result["code"] != 0) {
            return $this->fail(self::VALIDATE_ERROR, $result["errors"]);
        }

        $input['Qos'] = empty($input['Qos']) ? 0 : $input['Qos'];

        $res = $this->server->publishToTopic($input['ProductKey'], $input['TopicFullName'], $input['MessageContent'], $input['Qos']);
        return $this->success($res);
    }


    /**
     * @api {post} api/ali/sendMessageToDevice  发消息给设备并同步返回响应
     * @apiVersion 1.0.0
     * @apiName sendMessageToDevice
     * @apiGroup ALi
     *
     * @apiParam   {string} ProductKey 产品id
     * @apiParam   {string} DeviceName 设备名称
     * @apiParam   {string} RequestBase64Byte 请求消息内容，需要是经过Base64编码得到的字符串数据
     * @apiParam   {int} [Timeout] 表示等待设备回复消息的时间，单位是毫秒，允许范围是1000~5000
     *
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     * {
     * "RequestId":"41C4265E-F05D-4E2E-AB09-E031F501AF7F",
     * "Success":true,
     * "RrpcCode":"SUCCESS",
     * "PayloadBase64Byte":"d29ybGQgaGVsbG8="
     * "MessageId":889455942124347392
     * }
     */
    public function sendMessageToDevice(Request $request)
    {
        $input = $request->all();
        //校验
        $rules = array("ProductKey" => "required",
            "DeviceName" => "required",
            "RequestBase64Byte" => "required",
        );
        $messages = array("ProductKey.required" => "ProductKey为空",
            "DeviceName.required" => "device为空",
            "RequestBase64Byte.required" => "消息内容为空");
        $result = $this->validate($input, $rules, $messages);
        if ($result["code"] != 0) {
            return $this->fail(self::VALIDATE_ERROR, $result["errors"]);
        }

        $input['Timeout'] = empty($input['Timeout']) ? 1000 : $input['Timeout'];

        $res = $this->server->sendMessageToDevice($input['ProductKey'], $input['DeviceName'], base64_encode($input['RequestBase64Byte']), $input['Timeout']);
        return $this->success($res);
    }


    /**
     * @api {post} api/ali/sendBroadcastMessage  发送广播消息
     * @apiVersion 1.0.0
     * @apiName sendBroadcastMessage
     * @apiGroup ALi
     *
     * @apiParam   {string} ProductKey 产品id
     * @apiParam   {string} MessageContent 发送的消息，将消息内容二进制进行BASE64转码后得到的字符串
     * @apiParam   {string} TopicFullName 消息发送目的Topic名字，格式为 /broadcast/${productKey}/+，Topic第三段可以自定义
     *
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     * {
     * "RequestId":"41C4265E-F05D-4E2E-AB09-E031F501AF7F",
     * "Success":true,
     * "RrpcCode":"SUCCESS",
     * "PayloadBase64Byte":"d29ybGQgaGVsbG8="
     * "MessageId":889455942124347392
     * }
     */
    public function sendBroadcastMessage(Request $request)
    {
        $input = $request->all();
        //校验
        $rules = array("ProductKey" => "required",
            "MessageContent" => "required",
            "TopicFullName" => "required",
        );
        $messages = array("ProductKey.required" => "ProductKey为空",
            "TopicFullName.required" => "device为空",
            "MessageContent.required" => "消息内容为空");
        $result = $this->validate($input, $rules, $messages);
        if ($result["code"] != 0) {
            return $this->fail(self::VALIDATE_ERROR, $result["errors"]);
        }

        $res = $this->server->sendBroadcastMessage($input['ProductKey'], $input['TopicFullName'], $input['MessageContent']);
        return $this->success($res);
    }

    /**
     * @api {post} api/ali/device/shadow/get  获取设备影子
     * @apiVersion 1.0.0
     * @apiName getDeviceShadow
     * @apiGroup ALi
     *
     * @apiParam   {string} ProductKey 产品id
     * @apiParam   {string} DeviceName 设备名称，产品内唯一
     *
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     * {
     * "RequestId":"BB71E443-4447-4024-A000-EDE09922891E",
     * "Success":true,
     * "ShadowMessage":{...}
     * }
     */
    public function getDeviceShadow(Request $request)
    {
        $input = $request->all();
        //校验
        $rules = array("ProductKey" => "required",
            "DeviceName" => "required",
        );
        $messages = array("ProductKey.required" => "ProductKey为空",
            "DeviceName.required" => "device为空");
        $result = $this->validate($input, $rules, $messages);
        if ($result["code"] != 0) {
            return $this->fail(self::VALIDATE_ERROR, $result["errors"]);
        }

        $res = $this->server->getDeviceShadow($input['ProductKey'], $input['DeviceName']);
        return $this->success($res);
    }

    /**
     * @api {post} api/ali/device/shadow/update  更新设备影子
     * @apiVersion 1.0.0
     * @apiName updateDeviceShadow
     * @apiGroup ALi
     *
     * @apiParam   {string} ProductKey 产品id
     * @apiParam   {string} DeviceName 设备名称，产品内唯一
     * @apiParam   {string} ShadowMessage 设备影子信息
     *
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     * {
     * "RequestId":"BB71E443-4447-4024-A000-EDE09922891E",
     * "Success":true,
     * "ShadowMessage":{...}
     * }
     */
    public function updateDeviceShadow(Request $request)
    {
        $input = $request->all();
        //校验
        $rules = array("ProductKey" => "required",
            "DeviceName" => "required",
            "ShadowMessage" => "required",
        );
        $messages = array("ProductKey.required" => "ProductKey为空",
            "DeviceName.required" => "device为空",
            "ShadowMessage.required" => "影子信息为空");
        $result = $this->validate($input, $rules, $messages);
        if ($result["code"] != 0) {
            return $this->fail(self::VALIDATE_ERROR, $result["errors"]);
        }

        $res = $this->server->updateDeviceShadow($input['ProductKey'], $input['DeviceName'], $input['ShadowMessage']);
        return $this->success($res);
    }
}
